package pencarian;

import java.io.*;
import java.util.ArrayList;


class DFS{
    private Track currSolution; //tempat menyimpan urutan jalur
    private ArrayList<Coordinat> CoordinatSolution; //hasil yang berupa susunan koordinat
    private Coordinat currPoint; //penunjuk lokasi truk sekarang
    private int maxWeight; //jumlah barang maksimum yang bisa ditampung truk
    private int currWeight; //jumlah barang pada truk saat ini
    private int currItem; //index barang yang sedang dicari saat ini
    private ArrayList<Integer> currListItem; //list barang yang perlu dicari
    private MapTranslator Situation; //menggambarkan abstraksi map, jika ingin mendapatkan matriks map, gunakan Situation.getmap()
    static private ArrayList<Coordinat> visitedArray; //daftar node yg sudah visited
    static int jumlahVisitedArray;
    static private ArrayList<Coordinat> discoveredEdge;
    
    public DFS(Input inputan, String namafile){
        currSolution = new Track();
        maxWeight = inputan.getmaxWeight();
        currWeight = 0;
        currItem = 0;
        currListItem = new ArrayList<Integer>(inputan.getlistbarang());
        Situation = new MapTranslator(namafile);
        currPoint = new Coordinat(Situation.getPLocation());
        visitedArray = new ArrayList<Coordinat>();
        discoveredEdge = new ArrayList<Coordinat>();
        visitedArray.add(currPoint);
        discoveredEdge.add(currPoint);
        jumlahVisitedArray = 1;
    }
    
    public void doDFS(Coordinat currcoordinat, char Vendor){
        if(Situation.getMap()[currcoordinat.x][currcoordinat.y]==Vendor){
            System.out.println("Vendor "+Vendor+" ditemukan!");
        }
        else {
            for(int i = 0;i<3;i++){
                if (isAllowed(i)) {
                    for(int x=0;x<3;x++){
                        if(isAllowed(x)&& x!=i )discoveredEdge.add(currPoint);
                    }
                    visitedArray.add(currcoordinat.move(i));
                    doDFS(currcoordinat.move(i),Vendor);
                }
            }
        }
    }
    
    public void doSearch(Coordinat currcordinat)
    {
        /* selama list item belum habis, lakukan :
         * cek stack terdepan, buat cabang yg allowed, masukkan koordinat cabang ke dalam stack beserta jalurnya,
         * majukan currPoint ke stack selanjutnya, cek apakah goal atau bukan, jika ya, kurangi list item, jika list item
         * kosong, berarti pencarian selesai, jika tidak, 
         * ulangi pencarian dengan queue baru dimulai dari titik tersebut (jika truk masih mampu) atau kembali ke P (dengan
         * memanfaatkan jalur yg disimpan) jika truk sudah penuh, dan visitedArray yg baru, jika tidak, ulangi langkah :
         * buat cabang yg allowed, majukan currPoint ke queue selanjutnya...
         *
         */
         while(!discoveredEdge.isEmpty()){
            System.out.println("Pencarian di koordinat: ("+currcordinat.x+","+currcordinat.y+")");
            int i;
            for(i=0;i<=3;i++)
            {
                if(i==0)System.out.println("Mencoba Jalur Bawah");
                if(i==1)System.out.println("Mencoba Jalur Kiri");
                if(i==2)System.out.println("Mencoba Jalur Atas");
                if(i==3)System.out.println("Mencoba Jalur Kanan");
                if(isAllowed(i)){
                    currPoint = new Coordinat(currPoint.move(i));
                    currSolution.addJalur(i);
                    visitedArray.add(currPoint);
                    for(int x=0;x<3;x++){
                        if(isAllowed(x)&& x!=i )discoveredEdge.add(currPoint);
                    }
                    showVisitedArray();
                    jumlahVisitedArray++;
                    System.out.println("masuk ke Visited Array : ");
                    visitedArray.get(visitedArray.size()-1).showCoordinat();
                    System.out.println();
                    System.out.println("Jumlah visitedArray = "+jumlahVisitedArray);
                    if(Situation.getMap()[currPoint.x][currPoint.y]=='A') {
                        System.out.println("A Found!");
                    }
                    System.out.println(" "+currPoint.x+" "+currPoint.y+" "+Situation.getMap()[currPoint.x][currPoint.y]);
                    doSearch(new Coordinat(currPoint));
                }
                else{
                    System.out.println("Tidak bisa lewat!");
                }
            }
            Coordinat back = new Coordinat(discoveredEdge.get(discoveredEdge.size()-1));
            discoveredEdge.remove(discoveredEdge.size()-1);
//            doSearch(back);
         }
    }
    
    public static void main(String args[])throws IOException
    {
        ArrayList<Integer> listinput = new ArrayList<Integer>();
        listinput.add(1);
        listinput.add(2);
        Input in = new Input(2,listinput);
        DFS test = new DFS(in,"input1.txt");
        test.Situation.showMatrix();
//        test.testIsAllowed();
        test.doSearch(test.Situation.getPLocation());
//        test.doDFS(test.currPoint, 'A');
    }
    public boolean isAllowed(int i){
        //batasan-batasan, jika lewat dimensi map atau menabrak #
        if(!(   currPoint.move(i).x >= Situation.getSizeX() ||
                currPoint.move(i).x < 0                     ||   
                currPoint.move(i).y >= Situation.getSizeY() || 
                currPoint.move(i).y < 0
                )){
//            System.out.println("visitedArray.contains(currPoint.move(i)) "+visitedArray.contains(currPoint.move(i)));
            if( Situation.getMap()[currPoint.move(i).x][currPoint.move(i).y] == '#')
            {
                return false;
            }
            else{
                int n;//jumlah visited Array
                for (n = 0;n < visitedArray.size();n++){
                    if(visitedArray.get(n).isEqual(currPoint.move(i))){
                        return false;
                    }
                }
                return true;
            }
        }else {
//            System.out.println("Di luar arena!");
            return false;
        }
    }
    //method untuk mengembalikan hasil
    public ArrayList<Coordinat> getSolution(){
        return CoordinatSolution;
    }
    //method untuk menyusun CoordinatResult dari posisi awal P dan currSolution yang terbentuk
    public void createCoordinatResult(){
        
    }
    //method untuk mengetes betul tidaknya isAllowed
    public void testIsAllowed(){
        for(int j = 0;j < Situation.getSizeX();j++){
            for(int i = 0;i < Situation.getSizeY();i++){
                    currPoint  = new Coordinat(i,j);
                    System.out.print("("+isAllowed(0)+","+isAllowed(1)+","+isAllowed(2)+","+isAllowed(3)+") ");
            }
            System.out.println();
        }
    }
    public void showVisitedArray(){
        System.out.print("currvisitedArray = ");
        for(int n = 0;n<visitedArray.size();n++){
            visitedArray.get(n).showCoordinat();
        }
        System.out.println();
        System.out.print("currdiscoveredEdge = ");
        for(int n = 0;n<discoveredEdge.size();n++){
            discoveredEdge.get(n).showCoordinat();
        }
        System.out.println();
    }   
}
